জাভা জেনেরিক্সে Bounded Type Parameters ব্যবহার করে আপনি নির্দিষ্ট সীমার মধ্যে টাইপ প্যারামিটারগুলোকে সংজ্ঞায়িত করতে পারেন। এটি নিশ্চিত করে যে জেনেরিক ক্লাস, মেথড বা ইন্টারফেস কেবলমাত্র নির্দিষ্ট টাইপ বা টাইপগুলোর সাবক্লাস ব্যবহার করতে পারবে।
<T extends SuperClass>
T extends SuperClass
: এর মানে হলো, T
হবে SuperClass
বা SuperClass
এর কোনো সাবক্লাস।class Box<T extends Number> {
private T item;
public void setItem(T item) {
this.item = item;
}
public T getItem() {
return item;
}
public double getDoubleValue() {
return item.doubleValue(); // Number এর মেথড
}
}
public class Main {
public static void main(String[] args) {
Box<Integer> intBox = new Box<>();
intBox.setItem(100);
System.out.println("Value: " + intBox.getItem());
System.out.println("Double Value: " + intBox.getDoubleValue());
Box<Double> doubleBox = new Box<>();
doubleBox.setItem(99.9);
System.out.println("Value: " + doubleBox.getItem());
System.out.println("Double Value: " + doubleBox.getDoubleValue());
// Box<String> stringBox = new Box<>(); // কম্পাইল টাইম ত্রুটি
}
}
আউটপুট:
Value: 100
Double Value: 100.0
Value: 99.9
Double Value: 99.9
public class GenericMethodExample {
public static <T extends Comparable<T>> T findMax(T x, T y) {
return (x.compareTo(y) > 0) ? x : y;
}
public static void main(String[] args) {
System.out.println("Max of 10 and 20: " + findMax(10, 20));
System.out.println("Max of A and B: " + findMax("A", "B"));
}
}
আউটপুট:
Max of 10 and 20: 20
Max of A and B: B
class Example<T extends Number & Comparable<T>> {
private T value;
public Example(T value) {
this.value = value;
}
public boolean isGreaterThan(T other) {
return value.compareTo(other) > 0;
}
}
public class Main {
public static void main(String[] args) {
Example<Integer> example = new Example<>(10);
System.out.println("Is 10 greater than 5? " + example.isGreaterThan(5));
Example<Double> exampleDouble = new Example<>(15.5);
System.out.println("Is 15.5 greater than 20.0? " + exampleDouble.isGreaterThan(20.0));
// Example<String> exampleString = new Example<>("Test"); // কম্পাইল টাইম ত্রুটি
}
}
আউটপুট:
Is 10 greater than 5? true
Is 15.5 greater than 20.0? false
?
) এবং Bounded Wildcards:?
): যেকোনো টাইপ গ্রহণ করে।? extends T
: উপরের দিকে সীমাবদ্ধতা।? super T
: নিচের দিকে সীমাবদ্ধতা।import java.util.ArrayList;
import java.util.List;
public class WildcardExample {
public static void printNumbers(List<? extends Number> list) {
for (Number num : list) {
System.out.println(num);
}
}
public static void main(String[] args) {
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
List<Double> doubleList = new ArrayList<>();
doubleList.add(3.14);
doubleList.add(2.71);
printNumbers(intList);
printNumbers(doubleList);
}
}
আউটপুট:
1
2
3.14
2.71
Primitive টাইপ ব্যবহার করা যায় না: int
, double
ইত্যাদি সরাসরি জেনেরিক্সে ব্যবহার করা যায় না। তবে, Autoboxing এর মাধ্যমে Integer
, Double
ব্যবহার করা যায়।
List<int> list = new ArrayList<>(); // ত্রুটি
List<Integer> list = new ArrayList<>(); // সঠিক
Multiple Inheritance Allowed নয়: টাইপ প্যারামিটার একাধিক ক্লাস এক্সটেন্ড করতে পারে না। তবে, একটি ক্লাস এবং একাধিক ইন্টারফেস এক্সটেন্ড করা যায়।
<T extends ClassA & Interface1 & Interface2> // সঠিক
Bounded Type Parameters জাভা জেনেরিক্সের একটি শক্তিশালী বৈশিষ্ট্য যা কোডকে আরও রিডেবল, রিইউজেবল এবং টাইপ সেফ করে। এটি জেনেরিক ক্লাস এবং মেথডগুলিকে একটি নির্দিষ্ট টাইপ বা টাইপের সাবক্লাসের জন্য সীমাবদ্ধ করে আরও সুনির্দিষ্ট কাজ করার সুযোগ দেয়।
Bounded Type Parameters হল Java Generics-এর একটি ফিচার যা টাইপ প্যারামিটারকে নির্দিষ্ট একটি শ্রেণি বা ইন্টারফেসের মধ্যে সীমাবদ্ধ করে। এটি টাইপ প্যারামিটারকে একটি নির্দিষ্ট সীমার মধ্যে কাজ করতে বাধ্য করে।
Bounded Type Parameters নির্ধারণ করার জন্য extends
কীওয়ার্ড ব্যবহার করা হয়। এটি টাইপ প্যারামিটারকে একটি নির্দিষ্ট ক্লাস বা ইন্টারফেস এবং তার সাবক্লাসের মধ্যে সীমাবদ্ধ করে।
class ClassName<T extends SuperClass> {
// Class Definition
}
public class GenericClass<T extends Number> {
private T value;
public GenericClass(T value) {
this.value = value;
}
public double getDoubleValue() {
return value.doubleValue();
}
}
// Usage:
GenericClass<Integer> intObj = new GenericClass<>(10);
System.out.println(intObj.getDoubleValue());
GenericClass<Double> doubleObj = new GenericClass<>(5.5);
System.out.println(doubleObj.getDoubleValue());
// GenericClass<String> strObj = new GenericClass<>("Hello"); // Compile-time Error
Upper Bound (T extends SomeClass
)
টাইপ প্যারামিটার হবে নির্দিষ্ট ক্লাস বা ইন্টারফেস এবং তার সাবক্লাস।
উদাহরণ:
public static <T extends Number> double add(T a, T b) {
return a.doubleValue() + b.doubleValue();
}
public static void main(String[] args) {
System.out.println(add(5, 10)); // Valid
System.out.println(add(3.5, 2.5)); // Valid
// System.out.println(add("5", "10")); // Compile-time Error
}
Multiple Bounds (T extends Class & Interface
)
টাইপ প্যারামিটার একাধিক শ্রেণি বা ইন্টারফেসের সীমার মধ্যে থাকতে পারে।
উদাহরণ:
public class GenericClass<T extends Number & Comparable<T>> {
private T value;
public GenericClass(T value) {
this.value = value;
}
public boolean isGreaterThan(T other) {
return value.compareTo(other) > 0;
}
}
Unbounded Type (T
)
কোন সীমাবদ্ধতা নেই; যে কোনো টাইপ ব্যবহার করা যায়।
উদাহরণ:
public static <T> void print(T value) {
System.out.println(value);
}
টাইপ সেফটি নিশ্চিত করা
নির্দিষ্ট সীমার বাইরে কোন টাইপ ব্যবহার করতে গেলে compile-time এ এরর দেখা যায়।
public static <T extends Number> void printSquare(T number) {
System.out.println(number.doubleValue() * number.doubleValue());
}
// Usage:
printSquare(5); // Valid
printSquare(3.14); // Valid
// printSquare("Hello"); // Compile-time Error
Bounded Wildcard (? extends T
বা ? super T
) ব্যবহার করে Generics-এ আরও বেশি ডাইনামিক সুবিধা পাওয়া যায়।
public static void printList(List<? extends Number> list) {
for (Number num : list) {
System.out.println(num);
}
}
public static void addToList(List<? super Integer> list) {
list.add(10);
list.add(20);
}
Generics-এ bounded type parameters ব্যবহার করা হয় একটি নির্দিষ্ট টাইপ বা টাইপ রেঞ্জ সীমাবদ্ধ করতে। এভাবে আমরা টাইপ প্যারামিটারগুলোর সাথে আরও নির্দিষ্ট নিয়ম প্রয়োগ করতে পারি।
Upper bounded টাইপ প্যারামিটার একটি টাইপকে নির্ধারিত ক্লাস বা ইন্টারফেস (এবং তার সাবক্লাস/ইমপ্লিমেন্টেশন) এর মধ্যে সীমাবদ্ধ করে। এটি extends
কীওয়ার্ড ব্যবহার করে ঘোষণা করা হয়।
<T extends ClassName>
import java.util.ArrayList;
import java.util.List;
public class Main {
// Upper Bounded Generics Method
public static double sumOfNumbers(List<? extends Number> list) {
double sum = 0.0;
for (Number num : list) {
sum += num.doubleValue();
}
return sum;
}
public static void main(String[] args) {
List<Integer> intList = new ArrayList<>();
intList.add(10);
intList.add(20);
intList.add(30);
List<Double> doubleList = new ArrayList<>();
doubleList.add(5.5);
doubleList.add(10.5);
System.out.println("Sum of Integers: " + sumOfNumbers(intList));
System.out.println("Sum of Doubles: " + sumOfNumbers(doubleList));
}
}
Sum of Integers: 60.0
Sum of Doubles: 16.0
কী শিখলাম:
? extends Number
নির্দেশ করে যে লিস্টের টাইপ Number
বা তার সাবক্লাস হতে হবে (যেমন Integer
, Double
)।Lower bounded টাইপ প্যারামিটার একটি টাইপকে নির্দিষ্ট ক্লাস বা তার সুপারক্লাসের মধ্যে সীমাবদ্ধ করে। এটি super
কীওয়ার্ড ব্যবহার করে ঘোষণা করা হয়।
<T super ClassName>
import java.util.ArrayList;
import java.util.List;
public class Main {
// Lower Bounded Generics Method
public static void addNumbers(List<? super Integer> list) {
list.add(10);
list.add(20);
}
public static void main(String[] args) {
List<Number> numberList = new ArrayList<>();
addNumbers(numberList);
System.out.println("Number List: " + numberList);
}
}
Number List: [10, 20]
কী শিখলাম:
? super Integer
নির্দেশ করে যে লিস্টের টাইপ Integer
বা তার সুপারক্লাস হতে হবে (যেমন Number
, Object
)।বৈশিষ্ট্য | Upper Bounded | Lower Bounded |
---|---|---|
কীওয়ার্ড | extends | super |
কাজের ধরন | রিডিং ডেটার জন্য কার্যকর | লেখার/ডেটা যোগ করার জন্য কার্যকর |
টাইপ রেঞ্জ | নির্দিষ্ট ক্লাস বা তার সাবক্লাস | নির্দিষ্ট ক্লাস বা তার সুপারক্লাস |
?
হলো একটি wildcard যা টাইপ প্যারামিটারকে নমনীয় করে। এটি ? extends
এবং ? super
এর মাধ্যমে টাইপ রেঞ্জ নির্ধারণ করতে ব্যবহৃত হয়।
// Wildcard with Upper Bound
List<? extends Number> upperBoundList;
// Wildcard with Lower Bound
List<? super Integer> lowerBoundList;
Generics এ Upper এবং Lower Bounded Type Parameters টাইপ নিরাপত্তা ও ফ্লেক্সিবিলিটি বাড়ায়। এটি বড় ও জটিল জাভা প্রোজেক্টে বিশেষভাবে গুরুত্বপূর্ণ।
জাভা জেনেরিক্সে Wildcards ব্যবহার করে জেনেরিক টাইপের আরও বেশি নমনীয়তা অর্জন করা যায়। বিশেষত, Bounded Wildcards ব্যবহার করে নির্দিষ্ট সীমার মধ্যে জেনেরিক টাইপগুলিকে সীমাবদ্ধ করা যায়। এটি ডেটা টাইপগুলির মাঝে আরও ভালো টাইপ সুরক্ষা এবং পুনঃব্যবহারযোগ্য কোড লিখতে সাহায্য করে।
Wildcards হল একটি প্রশ্নবোধক চিহ্ন (?
), যা "কোনো টাইপ" বোঝায়। এটি তিনটি প্রধান ধরণের হতে পারে:
?
): যেকোনো টাইপ গ্রহণ করতে পারে।? extends Type
): নির্দিষ্ট টাইপ বা তার সাবটাইপ গ্রহণ করতে পারে।? super Type
): নির্দিষ্ট টাইপ বা তার সুপারটাইপ গ্রহণ করতে পারে।?
)?
ব্যবহার করা হয় যখন জেনেরিক টাইপের কোনো নির্দিষ্ট সীমা দরকার নেই।
import java.util.List;
public class Main {
public static void printList(List<?> list) {
for (Object obj : list) {
System.out.println(obj);
}
}
public static void main(String[] args) {
List<String> stringList = List.of("Java", "Generics", "Wildcard");
List<Integer> intList = List.of(1, 2, 3);
printList(stringList);
printList(intList);
}
}
? extends Type
)? extends Type
ব্যবহার করা হয় যেখানে জেনেরিক টাইপটি একটি নির্দিষ্ট টাইপের সাবক্লাস বা ইনটারফেস হতে হবে। এটি Covariant আচরণ প্রদান করে।
import java.util.List;
public class Main {
// Method to calculate sum of a list of Numbers or its subclasses
public static double sumList(List<? extends Number> list) {
double sum = 0.0;
for (Number num : list) {
sum += num.doubleValue();
}
return sum;
}
public static void main(String[] args) {
List<Integer> intList = List.of(1, 2, 3);
List<Double> doubleList = List.of(1.1, 2.2, 3.3);
System.out.println("Sum of intList: " + sumList(intList));
System.out.println("Sum of doubleList: " + sumList(doubleList));
}
}
Sum of intList: 6.0
Sum of doubleList: 6.6
? super Type
)? super Type
ব্যবহার করা হয় যেখানে জেনেরিক টাইপটি একটি নির্দিষ্ট টাইপের সুপারক্লাস হতে হবে। এটি Contravariant আচরণ প্রদান করে।
import java.util.List;
import java.util.ArrayList;
public class Main {
// Method to add elements into a list
public static void addElements(List<? super Integer> list) {
list.add(10);
list.add(20);
list.add(30);
}
public static void main(String[] args) {
List<Number> numberList = new ArrayList<>();
addElements(numberList);
System.out.println("Number List: " + numberList);
}
}
Number List: [10, 20, 30]
? extends
এর ক্ষেত্রে নতুন উপাদান যোগ করা যায় না (কেবলমাত্র null
যোগ করা যায়)।Wildcards এবং Bounded Types ব্যবহার করলে জেনেরিক কোড আরও বেশি শক্তিশালী এবং নমনীয় হয়। এগুলোর সঠিক ব্যবহার করলে টাইপ সুরক্ষা এবং কোড পুনঃব্যবহারযোগ্যতা বৃদ্ধি পায়।
Multiple Bounds জাভার জেনেরিক্সের একটি বৈশিষ্ট্য যা একটি টাইপ প্যারামিটারকে একাধিক শর্তে সীমাবদ্ধ করতে দেয়। এটি extends
কীওয়ার্ড ব্যবহার করে প্রয়োগ করা হয় এবং একটি ক্লাস বা ইন্টারফেসের সংমিশ্রণকে নির্দেশ করে।
সিনট্যাক্স:
<T extends ClassName & Interface1 & Interface2>
interface Drivable {
void drive();
}
interface Maintainable {
void maintain();
}
class Vehicle {
void start() {
System.out.println("Vehicle started");
}
}
public class MultiBoundExample<T extends Vehicle & Drivable & Maintainable> {
private T obj;
public MultiBoundExample(T obj) {
this.obj = obj;
}
public void operate() {
obj.start();
obj.drive();
obj.maintain();
}
}
class Car extends Vehicle implements Drivable, Maintainable {
@Override
public void drive() {
System.out.println("Car is driving");
}
@Override
public void maintain() {
System.out.println("Car is being maintained");
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car();
MultiBoundExample<Car> example = new MultiBoundExample<>(car);
example.operate();
}
}
Vehicle started
Car is driving
Car is being maintained
interface Readable {
void read();
}
interface Writable {
void write();
}
class MultiBoundInterfaceExample<T extends Readable & Writable> {
private T obj;
public MultiBoundInterfaceExample(T obj) {
this.obj = obj;
}
public void process() {
obj.read();
obj.write();
}
}
class Document implements Readable, Writable {
@Override
public void read() {
System.out.println("Reading the document");
}
@Override
public void write() {
System.out.println("Writing to the document");
}
}
public class Main {
public static void main(String[] args) {
Document doc = new Document();
MultiBoundInterfaceExample<Document> example = new MultiBoundInterfaceExample<>(doc);
example.process();
}
}
Reading the document
Writing to the document
ক্লাস সর্বদা প্রথমে থাকতে হবে:
<T extends Class & Interface1 & Interface2>
ভুল: <T extends Interface1 & Class>
।
একই সময়ে শুধুমাত্র একটি ক্লাস থাকতে পারে: একটি টাইপ প্যারামিটার একাধিক ক্লাস প্রসারিত করতে পারে না।
ভুল:
<T extends Class1 & Class2 & Interface>
Multiple Bounds জেনেরিক্স ব্যবহার করে টাইপ প্যারামিটারগুলিকে আরো কার্যকরী এবং শক্তিশালী করে। এটি জাভায় টাইপ সেফ এবং রিইউজেবল কোড লেখার একটি উন্নত পদ্ধতি।
Read more